package com.example.jnet.network;

import com.example.jnet.config.AppContext;
import com.example.jnet.config.ServerConfig;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.stereotype.Service;
import sun.net.ftp.FtpClientProvider;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

@Service
public class TcpServer {
    private static Logger logger = LoggerFactory.getLogger(TcpServer.class);

    private Executor threadPool = Executors.newFixedThreadPool(1);

    @Autowired
    private ServerConfig serverConfig;

    public void start() {
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                TcpServer tcpServer = AppContext.getAppContext().getBean(TcpServer.class);
                tcpServer.run();
            }
        });
    }

    public void run() {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new TcpServerInitializer());
            //.childOption(ChannelOption.AUTO_READ, false);

            ChannelFuture channelFuture = null;
            if (StringUtils.isBlank(serverConfig.getHost())) {
                channelFuture = b.bind(serverConfig.getPort()).sync();
            } else {
                channelFuture = b.bind(serverConfig.getHost(),
                        serverConfig.getPort()).sync();
            }
            logger.info("network listen port[" + serverConfig.getHost()
                    + ":" + serverConfig.getPort() + "] OK!");
        } catch (Exception e) {
            logger.error("e:" + e.getMessage(), e);
        }
    }
}